package teemo

import (
	"context"
	"time"

	"github.com/go-resty/resty/v2"
)

// New 创建一个新的 HTTP 客户端实例，可通过可选参数自定义超时、日志等配置。
// options: 可选的客户端配置函数（如 WithTimeout、WithLogger 等）。
// 返回值: *Client 新的客户端实例。
func New(options ...ClientOption) *Client {
	client := &Client{
		logger: globalLogger,
		resty:  resty.New(),
	}
	for _, option := range options {
		option(client)
	}
	return client
}

// NewRequest 创建一个新的泛型 HTTP 请求对象。
// client: 需要绑定的 Client 实例。
// 返回值: *Request[T] 泛型请求对象，可链式调用设置参数和发起请求。
func NewRequest[T interface{}](client *Client) *Request[T] {
	return &Request[T]{
		client: client,
		debug:  client.debug,
		logger: client.logger,
	}
}

// SendHttpPostRequest 发送一个 HTTP POST 请求，自动创建客户端并发起请求。
// ctx: 上下文对象，用于控制超时和取消。
// url: 请求地址。
// headers: 请求头（结构体、map等，支持多种格式）。
// data: 请求体数据。
// 返回值: 泛型 T 的响应结果，error 错误信息。
func SendHttpPostRequest[T interface{}](ctx context.Context, url string, headers interface{}, data interface{}) (result T, err error) {
	client := New(
		WithTimeout(60*time.Second),
		WithLogger(globalLogger),
	)
	return NewRequest[T](client).
		SetHeaders(headers).
		Post(ctx, url, data)
}

// SendHttpGetRequest 发送一个 HTTP GET 请求，自动创建客户端并发起请求。
// ctx: 上下文对象，用于控制超时和取消。
// url: 请求地址。
// headers: 请求头（结构体、map等，支持多种格式）。
// data: 查询参数（结构体、map等，自动转换为 query string）。
// 返回值: 泛型 T 的响应结果，error 错误信息。
func SendHttpGetRequest[T interface{}](ctx context.Context, url string, headers interface{}, data interface{}) (result T, err error) {
	client := New(
		WithTimeout(60*time.Second),
		WithLogger(globalLogger),
	)
	return NewRequest[T](client).
		SetHeaders(headers).
		Get(ctx, url, data)
}

// 发送http put请求
func SendHttpPutRequest[T interface{}](ctx context.Context, url string, headers interface{}, data interface{}) (result T, err error) {
	client := New(
		WithTimeout(60*time.Second),
		WithLogger(globalLogger),
	)
	return NewRequest[T](client).
		SetHeaders(headers).
		Put(ctx, url, data)
}

// 发送http delete请求
func SendHttpDeleteRequest[T interface{}](ctx context.Context, url string, headers interface{}, data interface{}) (result T, err error) {
	client := New(
		WithTimeout(60*time.Second),
		WithLogger(globalLogger),
	)
	return NewRequest[T](client).
		SetHeaders(headers).
		Delete(ctx, url, data)
}
